package t::TestUtils;

use strict;
use warnings;

use base 'Exporter';

use Test::More;
use Cwd;
use File::Copy;
use LWP::UserAgent;

my $apachectl = getcwd . "/testing/apache/bin/apachectl";
my $test_dir = getcwd . "/t";
my $pid_file = getcwd . "/testing/apache/logs/httpd.pid";

our @EXPORT = qw(
  test_apache
  test_url_base
  test_port
  user_agent
  test_dir
  default_content
);

my $apache_conf = "testing/apache/conf/httpd.conf";
my $original_conf = "testing/apache/conf/original/httpd.conf";
my $index = "testing/apache/htdocs/index.html";

sub test_apache {
  my ($conf, $tests) = @_;
  setup_apache($conf);
  eval { $tests->() };
  diag "tests threw error: $@" if $@;
  stop_apache();
}

sub setup_apache {
  my ($conf) = @_;
  stop_apache() if stat($pid_file);
  copy($original_conf, $apache_conf)
    or die "could not copy original httpd.conf from $original_conf to $apache_conf, $!";
  open my $fh, '>>', $apache_conf
    or die "cannot append to $apache_conf, $!";
  print $fh "\n\nLoadModule javascript_module modules/mod_javascript.so\n\n$conf\n\n";
  close $fh;
  system("$apachectl start") == 0
    or die "could not start apache";
  my $started;
  my $attempts = 40;
  while (! $started && $attempts--) {
    my $response = user_agent()->get(test_url_base() . "/");
    $started = $response->is_success;
    select undef, undef, undef, 0.2
      unless $started;
  }
  die "could not start apache"
    unless $started;
}

# for some reason apache doesn't always stop on the first attempt
# try 5 times, waiting two seconds on each attempt
sub stop_apache {
  my $stopped;
  my $attempts = 5;
  while (! $stopped && $attempts--) {
    system("$apachectl stop") == 0
      or die "could not stop apache";
    my $wait = 10;
    while (1) {
      $stopped = ! stat($pid_file);
      last if $stopped || ! $wait--;
      select undef, undef, undef, 0.1;
    }
  }
  die "apache did not stop"
    unless $stopped;
}

sub test_port {
  $ENV{TEST_PORT} || 9307;
}

sub test_url_base {
  'http://127.0.0.1:' . test_port();
}

sub user_agent {
  my $ua = LWP::UserAgent->new;
  $ua->timeout(10);
  $ua;
}

sub test_dir {
  $test_dir;
}

sub default_content {
  open my $fh, '<', $index
    or die "could not load in default content ($index), $!";
  local $/ = undef;
  my $content = <$fh>;
  close $fh;
  $content;
}

1;

